package plp.funcoo.expressions;

import plp.funcoo.environment.compilation.CompilationEnvironment;
import plp.funcoo.environment.compilation.Environment;
import plp.funcoo.environment.execution.ExecutionContext;
import plp.funcoo.environment.execution.ExecutionEnvironment;
import plp.funcoo.exceptions.ClassAlreadyDeclared;
import plp.funcoo.exceptions.ClassNotDeclared;
import plp.funcoo.exceptions.MethodAlreadDeclared;
import plp.funcoo.exceptions.MethodNotDeclared;
import plp.funcoo.exceptions.VarAlreadyDeclared;
import plp.funcoo.exceptions.VarNotDeclared;
import plp.funcoo.types.PrimitiveType;
import plp.funcoo.util.Type;
import plp.funcoo.value.IntegerValue;
import plp.funcoo.value.StringValue;


public class ExpLengh extends UnaryExpression{
	
	/**
	 * Controi uma Expressao de tamanho  com a expressao especificada
	 * assume-se que <code>exp</code> &eacute; uma expressao cuja avaliacao
	 * resulta num <code>ValorString</code>
	 */
	public ExpLengh(Expression exp) {
		super(exp, "length");
	}

	/**
	 * Retorna o valor da Expressao de tamanho.
	 */
	public ExecutionEnvironment evaluate(ExecutionEnvironment envi) throws VarNotDeclared, MethodNotDeclared, VarAlreadyDeclared, MethodAlreadDeclared {
		((ExecutionContext) envi).setValueAnalyzed(new IntegerValue( ((StringValue)getExp().evaluate(envi)).getValue().length()));
		return envi;
	}

	/**
	 * Realiza a verificacao de tipos desta expressao.
	 *
	 * @return <code>true</code> se os tipos da expressao sao validos;
	 *          <code>false</code> caso contrario.
	 */
	@Override
	public boolean typeCheck(CompilationEnvironment envi)
			throws VarAlreadyDeclared, VarNotDeclared, ClassAlreadyDeclared,
			ClassNotDeclared {
		return getExp().getType(envi).isString();
	}
	/**
	 * Retorna os tipos possiveis desta expressao.
	 *
	 * @return os tipos possiveis desta expressao.
	 */
	@Override
	public Type getType(Environment envi) throws VarNotDeclared,
			ClassNotDeclared {
		return PrimitiveType.Type_INT;
	}

	@Override
	public Expression makeCopy() {
		// TODO Auto-generated method stub
		return null;
	}


}
